home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / pb.c < prev    next >
C/C++ Source or Header  |  1999-02-04  |  12KB  |  437 lines

  1. /* $Id: pb.c,v 3.4 1998/04/01 02:58:52 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: pb.c,v $
  26.  * Revision 3.4  1998/04/01 02:58:52  brianp
  27.  * applied Miklos Fazekas's 3-31-98 Macintosh changes
  28.  *
  29.  * Revision 3.3  1998/03/05 02:59:05  brianp
  30.  * [RGBA]COMP wasn't being used in a few places
  31.  *
  32.  * Revision 3.2  1998/02/20 04:50:44  brianp
  33.  * implemented GL_SGIS_multitexture
  34.  *
  35.  * Revision 3.1  1998/02/15 01:32:37  brianp
  36.  * fixed a comment
  37.  *
  38.  * Revision 3.0  1998/01/31 21:00:28  brianp
  39.  * initial rev
  40.  *
  41.  */
  42.  
  43.  
  44. /*
  45.  * Pixel buffer:
  46.  *
  47.  * As fragments are produced (by point, line, and bitmap drawing) they
  48.  * are accumlated in a buffer.  When the buffer is full or has to be
  49.  * flushed (glEnd), we apply all enabled rasterization functions to the
  50.  * pixels and write the results to the display buffer.  The goal is to
  51.  * maximize the number of pixels processed inside loops and to minimize
  52.  * the number of function calls.
  53.  */
  54.  
  55.  
  56.  
  57. #ifdef PC_HEADER
  58. #include "all.h"
  59. #else
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #include "alpha.h"
  63. #include "alphabuf.h"
  64. #include "blend.h"
  65. #include "depth.h"
  66. #include "fog.h"
  67. #include "logic.h"
  68. #include "macros.h"
  69. #include "masking.h"
  70. #include "pb.h"
  71. #include "scissor.h"
  72. #include "stencil.h"
  73. #include "texture.h"
  74. #include "types.h"
  75. #endif
  76.  
  77.  
  78.  
  79. /*
  80.  * Allocate and initialize a new pixel buffer structure.
  81.  */
  82. struct pixel_buffer *gl_alloc_pb(void)
  83. {
  84.    struct pixel_buffer *pb;
  85.    pb = (struct pixel_buffer *) calloc(sizeof(struct pixel_buffer), 1);
  86.    if (pb) {
  87.       int i;
  88.       /* set non-zero fields */
  89.       pb->primitive = GL_BITMAP;
  90.       /* Set all lambda values to 0.0 since we don't do mipmapping for
  91.        * points or lines and want to use the level 0 texture image.
  92.        */
  93.       for (i=0; i<PB_SIZE; i++) {
  94.      pb->lambda[i] = 0.0;
  95.       }
  96.    }
  97.    return pb;
  98. }
  99.  
  100.  
  101.  
  102.  
  103. /*
  104.  * When the pixel buffer is full, or needs to be flushed, call this
  105.  * function.  All the pixels in the pixel buffer will be subjected
  106.  * to texturing, scissoring, stippling, alpha testing, stenciling,
  107.  * depth testing, blending, and finally written to the frame buffer.
  108.  */
  109. void gl_flush_pb( GLcontext *ctx )
  110. {
  111.    struct pixel_buffer* PB = ctx->PB;
  112.  
  113.    GLubyte mask[PB_SIZE];
  114.    GLubyte saved[PB_SIZE][4];
  115.  
  116.    if (PB->count==0)  goto CleanUp;
  117.  
  118.    /* initialize mask array and clip pixels simultaneously */
  119.    {
  120.       GLint xmin = ctx->Buffer->Xmin;
  121.       GLint xmax = ctx->Buffer->Xmax;
  122.       GLint ymin = ctx->Buffer->Ymin;
  123.       GLint ymax = ctx->Buffer->Ymax;
  124.       GLint *x = PB->x;
  125.       GLint *y = PB->y;
  126.       GLuint i, n = PB->count;
  127.       for (i=0;i<n;i++) {
  128.      mask[i] = (x[i]>=xmin) & (x[i]<=xmax) & (y[i]>=ymin) & (y[i]<=ymax);
  129.       }
  130.    }
  131.  
  132.    if (ctx->Visual->RGBAflag) {
  133.       /* RGBA COLOR PIXELS */
  134.       if (PB->mono && ctx->MutablePixels) {
  135.      /* Copy flat color to all pixels */
  136.      GLuint i;
  137.      for (i=0; i<PB->count; i++) {
  138.         PB->rgba[i][RCOMP] = PB->color[RCOMP];
  139.         PB->rgba[i][GCOMP] = PB->color[GCOMP];
  140.         PB->rgba[i][BCOMP] = PB->color[BCOMP];
  141.         PB->rgba[i][ACOMP] = PB->color[ACOMP];
  142.      }
  143.       }
  144.  
  145.       /* If each pixel can be of a different color... */
  146.       if (ctx->MutablePixels || !PB->mono) {
  147.  
  148.      if (ctx->Texture.Enabled) {
  149.         gl_texture_pixels( ctx, 0,
  150.                    PB->count, PB->s, PB->t, PB->u, PB->lambda,
  151.                    PB->rgba);
  152.      }
  153.  
  154.      if (ctx->Fog.Enabled
  155.          && (ctx->Hint.Fog==GL_NICEST || PB->primitive==GL_BITMAP
  156.          || ctx->Texture.Enabled)) {
  157.         gl_fog_rgba_pixels( ctx, PB->count, PB->z, PB->rgba );
  158.      }
  159.  
  160.      /* Scissoring already done above */
  161.  
  162.      if (ctx->Color.AlphaEnabled) {
  163. #ifndef __STORM__
  164.         if (gl_alpha_test( ctx, PB->count, PB->rgba, mask )==0) {
  165. #else
  166.         if (gl_alpha_test( ctx, PB->count, (CONST GLubyte(*)[4])PB->rgba, mask )==0) {
  167. #endif
  168.            goto CleanUp;
  169.         }
  170.      }
  171.  
  172.      if (ctx->Stencil.Enabled) {
  173.         /* first stencil test */
  174.         if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
  175.            goto CleanUp;
  176.         }
  177.         /* depth buffering w/ stencil */
  178.         gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  179.      }
  180.      else if (ctx->Depth.Test) {
  181.         /* regular depth testing */
  182.         (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  183.      }
  184.  
  185.      if (ctx->RasterMask & NO_DRAW_BIT) {
  186.         goto CleanUp;
  187.      }
  188.  
  189.      if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  190.         /* make a copy of the colors */
  191.         MEMCPY( saved, PB->rgba, PB->count * 4 * sizeof(GLubyte) );
  192.      }
  193.  
  194.      if (ctx->Color.SWLogicOpEnabled) {
  195.         gl_logicop_rgba_pixels( ctx, PB->count, PB->x, PB->y,
  196.                     PB->rgba, mask);
  197.      }
  198.      else if (ctx->Color.BlendEnabled) {
  199.         gl_blend_pixels( ctx, PB->count, PB->x, PB->y, PB->rgba, mask);
  200.      }
  201.  
  202.      if (ctx->Color.SWmasking) {
  203.         gl_mask_rgba_pixels(ctx, PB->count, PB->x, PB->y, PB->rgba, mask);
  204.      }
  205.  
  206.      /* write pixels */
  207. #ifndef __STORM__
  208.      (*ctx->Driver.WriteRGBAPixels)( ctx, PB->count, PB->x, PB->y,
  209.                      PB->rgba, mask );
  210. #else
  211.      (*ctx->Driver.WriteRGBAPixels)( ctx, PB->count, PB->x, PB->y,
  212.                      (CONST GLubyte(*)[4])PB->rgba, mask );
  213. #endif
  214.      if (ctx->RasterMask & ALPHABUF_BIT) {
  215. #ifndef __STORM__
  216.         gl_write_alpha_pixels( ctx, PB->count, PB->x, PB->y, PB->rgba, mask );
  217. #else
  218.         gl_write_alpha_pixels( ctx, PB->count, PB->x, PB->y, (CONST GLubyte(*)[4])PB->rgba, mask );
  219. #endif
  220.      }
  221.  
  222.      if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  223.         /*** Also draw to back buffer ***/
  224.         (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  225.         if (ctx->Color.SWLogicOpEnabled) {
  226.            gl_logicop_rgba_pixels( ctx, PB->count, PB->x, PB->y,
  227.                        PB->rgba, mask);
  228.         }
  229.         else if (ctx->Color.BlendEnabled) {
  230.            gl_blend_pixels( ctx, PB->count, PB->x, PB->y, saved, mask );
  231.         }
  232.         if (ctx->Color.SWmasking) {
  233.            gl_mask_rgba_pixels(ctx, PB->count, PB->x, PB->y, saved, mask);
  234.         }
  235. #ifndef __STORM__
  236.         (*ctx->Driver.WriteRGBAPixels)( ctx, PB->count, PB->x, PB->y,
  237.                         saved, mask);
  238. #else
  239.         (*ctx->Driver.WriteRGBAPixels)( ctx, PB->count, PB->x, PB->y,
  240.                         (CONST GLubyte(*)[4])saved, mask);
  241. #endif
  242.         if (ctx->RasterMask & ALPHABUF_BIT) {
  243.            ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  244. #ifndef __STORM__
  245.            gl_write_alpha_pixels( ctx, PB->count, PB->x, PB->y,
  246.                       saved, mask );
  247. #else
  248.            gl_write_alpha_pixels( ctx, PB->count, PB->x, PB->y,
  249.                       (CONST GLubyte(*)[4])saved, mask );
  250. #endif
  251.            ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  252.         }
  253.         (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  254.         /*** ALL DONE ***/
  255.      }
  256.       }
  257.       else {
  258.      /* Same color for all pixels */
  259.  
  260.      /* Scissoring already done above */
  261.  
  262.      if (ctx->Color.AlphaEnabled) {
  263. #ifndef __STORM__
  264.         if (gl_alpha_test( ctx, PB->count, PB->rgba, mask )==0) {
  265. #else
  266.         if (gl_alpha_test( ctx, PB->count, (CONST GLubyte(*)[4])PB->rgba, mask )==0) {
  267. #endif
  268.            goto CleanUp;
  269.         }
  270.      }
  271.  
  272.      if (ctx->Stencil.Enabled) {
  273.         /* first stencil test */
  274.         if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
  275.            goto CleanUp;
  276.         }
  277.         /* depth buffering w/ stencil */
  278.         gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  279.      }
  280.      else if (ctx->Depth.Test) {
  281.         /* regular depth testing */
  282.         (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  283.      }
  284.  
  285.      if (ctx->RasterMask & NO_DRAW_BIT) {
  286.         goto CleanUp;
  287.      }
  288.  
  289.      /* write pixels */
  290.      {
  291.         GLubyte red, green, blue, alpha;
  292.         red   = PB->color[RCOMP];
  293.         green = PB->color[GCOMP];
  294.         blue  = PB->color[BCOMP];
  295.         alpha = PB->color[ACOMP];
  296.         (*ctx->Driver.Color)( ctx, red, green, blue, alpha );
  297.      }
  298.      (*ctx->Driver.WriteMonoRGBAPixels)( ctx, PB->count, PB->x, PB->y, mask );
  299.      if (ctx->RasterMask & ALPHABUF_BIT) {
  300.         gl_write_mono_alpha_pixels( ctx, PB->count, PB->x, PB->y,
  301.                     PB->color[ACOMP], mask );
  302.      }
  303.  
  304.      if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  305.         /*** Also render to back buffer ***/
  306.         (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  307.         (*ctx->Driver.WriteMonoRGBAPixels)( ctx, PB->count, PB->x, PB->y, mask );
  308.         if (ctx->RasterMask & ALPHABUF_BIT) {
  309.            ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  310.            gl_write_mono_alpha_pixels( ctx, PB->count, PB->x, PB->y,
  311.                        PB->color[ACOMP], mask );
  312.            ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  313.         }
  314.         (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  315.      }
  316.      /*** ALL DONE ***/
  317.       }
  318.    }
  319.    else {
  320.       /* COLOR INDEX PIXELS */
  321.  
  322.       /* If we may be writting pixels with different indexes... */
  323.       if (PB->mono && ctx->MutablePixels) {
  324.      /* copy index to all pixels */
  325.      GLuint n = PB->count, indx = PB->index;
  326.      GLuint *pbindex = PB->i;
  327.      do {
  328.         *pbindex++ = indx;
  329.         n--;
  330.      } while (n);
  331.       }
  332.  
  333.       if (ctx->MutablePixels || !PB->mono) {
  334.      /* Pixel color index may be modified */
  335.      GLuint *isave = (GLuint*)saved;
  336.  
  337.      if (ctx->Fog.Enabled
  338.          && (ctx->Hint.Fog==GL_NICEST || PB->primitive==GL_BITMAP)) {
  339.         gl_fog_ci_pixels( ctx, PB->count, PB->z, PB->i );
  340.      }
  341.  
  342.      /* Scissoring already done above */
  343.  
  344.      if (ctx->Stencil.Enabled) {
  345.         /* first stencil test */
  346.         if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
  347.            goto CleanUp;
  348.         }
  349.         /* depth buffering w/ stencil */
  350.         gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  351.      }
  352.      else if (ctx->Depth.Test) {
  353.         /* regular depth testing */
  354.         (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  355.      }
  356.  
  357.      if (ctx->RasterMask & NO_DRAW_BIT) {
  358.         goto CleanUp;
  359.      }
  360.  
  361.      if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  362.         /* make a copy of the indexes */
  363.         MEMCPY( isave, PB->i, PB->count * sizeof(GLuint) );
  364.      }
  365.  
  366.      if (ctx->Color.SWLogicOpEnabled) {
  367.         gl_logicop_ci_pixels( ctx, PB->count, PB->x, PB->y, PB->i, mask );
  368.      }
  369.  
  370.      if (ctx->Color.SWmasking) {
  371.         gl_mask_index_pixels( ctx, PB->count, PB->x, PB->y, PB->i, mask );
  372.      }
  373.  
  374.      /* write pixels */
  375.      (*ctx->Driver.WriteCI32Pixels)( ctx, PB->count, PB->x, PB->y,
  376.                       PB->i, mask );
  377.  
  378.      if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  379.         /*** Also write to back buffer ***/
  380.         (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  381.         MEMCPY( PB->i, isave, PB->count * sizeof(GLuint) );
  382.         if (ctx->Color.SWLogicOpEnabled) {
  383.            gl_logicop_ci_pixels( ctx, PB->count, PB->x, PB->y, PB->i, mask );
  384.         }
  385.         if (ctx->Color.SWmasking) {
  386.            gl_mask_index_pixels( ctx, PB->count, PB->x, PB->y,
  387.                      PB->i, mask );
  388.         }
  389.         (*ctx->Driver.WriteCI32Pixels)( ctx, PB->count, PB->x, PB->y,
  390.                          PB->i, mask );
  391.         (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  392.      }
  393.  
  394.      /*** ALL DONE ***/
  395.       }
  396.       else {
  397.      /* Same color index for all pixels */
  398.  
  399.      /* Scissoring already done above */
  400.  
  401.      if (ctx->Stencil.Enabled) {
  402.         /* first stencil test */
  403.         if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
  404.            goto CleanUp;
  405.         }
  406.         /* depth buffering w/ stencil */
  407.         gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  408.      }
  409.      else if (ctx->Depth.Test) {
  410.         /* regular depth testing */
  411.         (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  412.      }
  413.      
  414.      if (ctx->RasterMask & NO_DRAW_BIT) {
  415.         goto CleanUp;
  416.      }
  417.  
  418.      /* write pixels */
  419.      (*ctx->Driver.Index)( ctx, PB->index );
  420.      (*ctx->Driver.WriteMonoCIPixels)( ctx, PB->count, PB->x, PB->y, mask );
  421.  
  422.      if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  423.         /*** Also write to back buffer ***/
  424.         (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  425.         (*ctx->Driver.WriteMonoCIPixels)( ctx, PB->count, PB->x, PB->y, mask );
  426.         (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  427.      }
  428.      /*** ALL DONE ***/
  429.       }
  430.    }
  431.  
  432. CleanUp:
  433.    PB->count = 0;
  434. }
  435.  
  436.  
  437.